// @ts-nocheck import { PermissionAction } from '@supabase/shared-types/out/constants' import { useParams } from 'common' import { partition } from 'lodash' import { ArrowRight, GitMerge, MessageCircle, MoreVertical, Shield, X } from 'lucide-react' import { useRouter } from 'next/router' import { PropsWithChildren } from 'react' import { toast } from 'sonner' import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, Tooltip, } from 'ui' import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader' import { BranchManagementSection, BranchRow, } from '@/components/interfaces/BranchManagement/BranchPanels' import { BranchSelector } from '@/components/interfaces/BranchManagement/BranchSelector' import { PullRequestsEmptyState } from '@/components/interfaces/BranchManagement/EmptyStates' import BranchLayout from '@/components/layouts/BranchLayout/BranchLayout' import DefaultLayout from '@/components/layouts/DefaultLayout' import { PageLayout } from '@/components/layouts/PageLayout/PageLayout' import { ScaffoldContainer, ScaffoldSection } from '@/components/layouts/Scaffold' import AlertError from '@/components/ui/AlertError' import { DocsButton } from '@/components/ui/DocsButton' import NoPermission from '@/components/ui/NoPermission' import { useBranchUpdateMutation } from '@/data/branches/branch-update-mutation' import { Branch, useBranchesQuery } from '@/data/branches/branches-query' import { useGitHubConnectionsQuery } from '@/data/integrations/github-connections-query' import { useSendEventMutation } from '@/data/telemetry/send-event-mutation' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' import { DOCS_URL } from '@/lib/constants' import type { NextPageWithLayout } from '@/types' const MergeRequestsPage: NextPageWithLayout = () => { const router = useRouter() const { ref } = useParams() const { data: project } = useSelectedProjectQuery() const { data: selectedOrg } = useSelectedOrganizationQuery() const isBranch = project?.parent_project_ref !== undefined const projectRef = project !== undefined ? (isBranch ? project.parent_project_ref : ref) : undefined const { can: canReadBranches, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions( PermissionAction.READ, 'preview_branches' ) const { data: connections, error: connectionsError, isError: isErrorConnections, } = useGitHubConnectionsQuery({ organizationId: selectedOrg?.id, }) const { data: branches = [], error: branchesError, isPending: isLoadingBranches, isError: isErrorBranches, } = useBranchesQuery({ projectRef }) const [[mainBranch], previewBranchesUnsorted] = partition(branches, (branch) => branch.is_default) const previewBranches = previewBranchesUnsorted.sort((a, b) => new Date(a.updated_at) < new Date(b.updated_at) ? 1 : -1 ) const mergeRequestBranches = previewBranches.filter( (branch) => branch.pr_number !== undefined || (branch.review_requested_at !== undefined && branch.review_requested_at !== null) ) const currentBranch = branches?.find((branch) => branch.project_ref === ref) const isCurrentBranchReadyForReview = !!currentBranch?.review_requested_at const githubConnection = connections?.find((connection) => connection.project.ref === projectRef) const repo = githubConnection?.repository.name ?? '' const isError = isErrorConnections || isErrorBranches const isGithubConnected = githubConnection !== undefined const { mutate: sendEvent } = useSendEventMutation() const { mutate: updateBranch, isPending: isUpdating } = useBranchUpdateMutation({ onError: () => { toast.error(`Failed to update the branch`) }, }) const handleMarkBranchForReview = ({ project_ref: branchRef, parent_project_ref: projectRef, persistent, }: Branch) => { updateBranch( { branchRef, projectRef, requestReview: true, }, { onSuccess: () => { toast.success('Merge request created') // Track merge request creation sendEvent({ action: 'branch_create_merge_request_button_clicked', properties: { branchType: persistent ? 'persistent' : 'preview', origin: 'merge_page', }, groups: { project: projectRef ?? 'Unknown', organization: selectedOrg?.slug ?? 'Unknown', }, }) router.push(`/project/${branchRef}/merge`) }, } ) } const handleCloseMergeRequest = ({ project_ref: branchRef, parent_project_ref: projectRef, }: Branch) => { updateBranch( { branchRef, projectRef, requestReview: false, }, { onSuccess: () => { toast.success('Merge request closed') // Track merge request closed sendEvent({ action: 'branch_close_merge_request_button_clicked', groups: { project: projectRef ?? 'Unknown', organization: selectedOrg?.slug ?? 'Unknown', }, }) }, } ) } const generateCreatePullRequestURL = (branch?: string) => { if (githubConnection === undefined) return 'https://github.com' return branch !== undefined ? `https://github.com/${githubConnection.repository.name}/compare/${mainBranch?.git_branch}...${branch}` : `https://github.com/${githubConnection.repository.name}/compare` } return (
{isPermissionsLoaded && !canReadBranches ? ( ) : ( <> {isErrorConnections && ( )} {isErrorBranches && ( )} {!isError && (
{isBranch && !isCurrentBranchReadyForReview && currentBranch && (
{currentBranch.name} last viewed
)} {isLoadingBranches ? (
) : mergeRequestBranches.length > 0 ? ( mergeRequestBranches.map((branch) => { const isPR = branch.pr_number !== undefined const rowLink = isPR ? `https://github.com/${repo}/pull/${branch.pr_number}` : `/project/${branch.project_ref}/merge` return ( {branch.name}
{branch.pr_number ? (

#{branch.pr_number}

) : ( <>

{mainBranch.name}

)}
} repo={repo} branch={branch} rowLink={rowLink} external={isPR} rowActions={ // We always want to show the action button to close a merge request // when user has requested review from dashboard. It doesn't matter // whether the branch is linked to a GitHub PR. branch.review_requested_at && (
)} )}
) } const MergeRequestsPageWrapper = ({ children }: PropsWithChildren<{}>) => { const router = useRouter() const { ref } = useParams() const { data: project } = useSelectedProjectQuery() const { data: selectedOrg } = useSelectedOrganizationQuery() const isBranch = project?.parent_project_ref !== undefined const projectRef = project !== undefined ? (isBranch ? project.parent_project_ref : ref) : undefined const { data: branches } = useBranchesQuery({ projectRef }) const previewBranches = (branches || []).filter((b) => !b.is_default) const { mutate: sendEvent } = useSendEventMutation() const { mutate: updateBranch, isPending: isUpdating } = useBranchUpdateMutation({ onError: () => { toast.error(`Failed to update the branch`) }, }) const handleMarkBranchForReview = ({ project_ref: branchRef, parent_project_ref: projectRef, persistent, }: Branch) => { updateBranch( { branchRef, projectRef, requestReview: true, }, { onSuccess: () => { toast.success('Merge request created') // Track merge request creation sendEvent({ action: 'branch_create_merge_request_button_clicked', properties: { branchType: persistent ? 'persistent' : 'preview', origin: 'branch_selector', }, groups: { project: projectRef ?? 'Unknown', organization: selectedOrg?.slug ?? 'Unknown', }, }) router.push(`/project/${branchRef}/merge`) }, } ) } return ( } secondaryActions={
} > {children}
) } MergeRequestsPage.getLayout = (page) => { return ( {page} ) } export default MergeRequestsPage